package com.emapp.lccode.fragment

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.viewModelScope
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.services.core.AMapException
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import com.emapp.lccode.R
import com.emapp.lccode.adapter.GridImageAdapter
import com.emapp.lccode.base.BaseConfig
import com.emapp.lccode.base.BaseFragment1
import com.emapp.lccode.base.EventBusConfig.REFRESH_ADDRESS
import com.emapp.lccode.base.EventBusModel
import com.emapp.lccode.bean.DeviceKt
import com.emapp.lccode.bean.ProblemTypeKt
import com.emapp.lccode.bean.UpLatLngKt
import com.emapp.lccode.databinding.FragmentReport0Binding
import com.emapp.lccode.mode.OrderKtViewModel
import com.emapp.lccode.utils.DividerOrientation
import com.emapp.lccode.utils.GlideEngine
import com.emapp.lccode.utils.ImageFileCompressEngine
import com.emapp.lccode.utils.MeSandboxFileEngine
import com.emapp.lccode.utils.MmkvUtil
import com.emapp.lccode.utils.MyExternalPreviewEventListener
import com.emapp.lccode.utils.approveTypes
import com.emapp.lccode.utils.divider
import com.emapp.lccode.utils.formTypes
import com.emapp.lccode.utils.getColorExt
import com.emapp.lccode.utils.grid
import com.emapp.lccode.utils.setOnclickNoRepeat
import com.emapp.lccode.utils.showMessage
import com.emapp.lccode.utils.toEntity
import com.emapp.lccode.utils.toJsonStr
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.hjq.toast.Toaster
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.config.SelectModeConfig
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.style.PictureSelectorStyle
import com.luck.picture.lib.utils.MediaUtils
import com.mylhyl.circledialog.CircleDialog
import com.umeng.commonsdk.stateless.UMSLEnvelopeBuild
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import me.hgj.jetpackmvvm.ext.launch
import me.hgj.jetpackmvvm.ext.parseState
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File

class ReportAddKtFragment : BaseFragment1<OrderKtViewModel, FragmentReport0Binding>(),
    AMapLocationListener, GeocodeSearch.OnGeocodeSearchListener {

    private var mData: ArrayList<LocalMedia> = arrayListOf()
    private var problem_type: ArrayList<ProblemTypeKt> = arrayListOf()
    private val imageAdapter: GridImageAdapter by lazy { GridImageAdapter(activity, mData) }
    lateinit var launcherResult: ActivityResultLauncher<Intent>
    private lateinit var locationClient: AMapLocationClient
    private var imageIds = ""
    private var latlng: UpLatLngKt? = null
    private var device_id = ""//设备id
    private var question_sta = "0"//设备状态 0正常 1 异常
    private var form_type = ""//问题来源 0内部巡检 1巡管员 2投诉报修 3电话报修
    private var approve_type = "1"// 1内部工单 2保险工单
    private var work_type = ""//问题类型大类
    private var son_type = ""//问题类型子类
    private var address = ""//
    private var content = ""//问题描述
    private var remark = ""//备注remark
    private var device: DeviceKt? = null
    val geocoderSearch: GeocodeSearch by lazy { GeocodeSearch(requireActivity()) }

    companion object {
        fun newInstance(status: String): ReportAddKtFragment {
            val args = Bundle()
            args.putString("status", status)
            val fragment = ReportAddKtFragment()
            fragment.arguments = args
            return fragment
        }
    }

    override fun initView(savedInstanceState: Bundle?) {
        EventBus.getDefault().register(this)
        val status = arguments?.getString("status").toString()
        // var bundles = requireActivity().intent.extras
        // device = bundles?.getParcelable<DeviceKt>("device")
       // device = requireActivity().intent.extras?.getSerializable("device") as DeviceKt?
        val inf = MmkvUtil.getString("device","")
        if (inf.isNotEmpty()){
            device= inf.toEntity<DeviceKt>()!!
        }

        device_id = device?.id ?: ""
        mViewBind.tvName.text = device?.name ?: ""
        AMapLocationClient.updatePrivacyShow(activity, true, true)
        AMapLocationClient.updatePrivacyAgree(activity, true)
        geocoderSearch.setOnGeocodeSearchListener(this)
        launcherResult = createActivityResultLauncher()
        mViewBind.rvList.run {
            grid(4)
            adapter = imageAdapter
            divider {
                orientation = DividerOrientation.HORIZONTAL
                includeVisible = true
                setDivider(10, true)
                setColor(getColorExt(R.color.white))
            }
        }
        imageAdapter.run {
            selectMax = BaseConfig.selectMaxImage
            setOnItemClickListener(object : GridImageAdapter.OnItemClickListener {
                override fun onItemClick(v: View?, position: Int) {
                    PictureSelector.create(this@ReportAddKtFragment)
                        .openPreview()
                        .setImageEngine(GlideEngine.createGlideEngine())
                        .setSelectorUIStyle(PictureSelectorStyle())
                        .isPreviewFullScreenMode(true)
                        .setExternalPreviewEventListener(MyExternalPreviewEventListener(this@run))
                        .startActivityPreview(position, true, data)
                }

                override fun openPicture() {
                    // 进入相册
                    PictureSelector.create(this@ReportAddKtFragment)
                        .openGallery(SelectMimeType.ofImage())
                        .setSelectorUIStyle(PictureSelectorStyle())
                        .setImageEngine(GlideEngine.createGlideEngine()) //.setCropEngine(getCropFileEngine())
                        .setCompressEngine(ImageFileCompressEngine())
                        .setSandboxFileEngine(MeSandboxFileEngine())
                        .setSelectionMode(SelectModeConfig.MULTIPLE)
                        .isDisplayCamera(true)
                        .setMaxSelectNum(BaseConfig.selectMaxImage)
                        .setSelectedData(data).also {
                            it.forResult(launcherResult)
                        }
                }

            })
        }
        mViewBind.rgType.setOnCheckedChangeListener { group, checkedId ->
            when (checkedId) {
                R.id.rb_1 -> {
                    mViewBind.lvYichang.visibility = View.GONE
                    question_sta = "0"
                }

                R.id.rb_2 -> {
                    mViewBind.lvYichang.visibility = View.VISIBLE
                    question_sta = "1"
                }
                R.id.rb_3 -> {
                    mViewBind.lvYichang.visibility = View.VISIBLE
                    question_sta = "2"
                }
                R.id.rb_4 -> {
                    mViewBind.lvYichang.visibility = View.VISIBLE
                    question_sta = "3"
                }
            }
        }
    }

    /**
     * 懒加载
     */
    override fun lazyLoadData() {
        initLocation()
    }

    override fun createObserver() {

        mViewModel.run {
            problemTypes.observe(viewLifecycleOwner) { resultState ->
                parseState(resultState, {
                    problem_type.clear()
                    it.forEach { typeKt ->
                        if (typeKt.pid == "0") {
                            it.forEach { typeKt2 ->
                                if (typeKt.id == typeKt2.pid) {
                                    typeKt.problemType2.add(typeKt2)
                                }
                            }
                            problem_type.add(typeKt)
                        }
                    }

                    CircleDialog.Builder()
                        .setItems(problem_type) { view, position ->
                            if (problem_type[position].problemType2.size == 0) {
                                mViewBind.tvType.text = problem_type[position].itemLabel
                                work_type = problem_type[position].id
                                son_type = ""
                            } else {
                                CircleDialog.Builder()
                                    .setItems(problem_type[position].problemType2) { _, position2 ->
                                        mViewBind.tvType.text =
                                            problem_type[position].itemLabel + "," + problem_type[position].problemType2[position2].itemLabel
                                        work_type = problem_type[position].id
                                        son_type = problem_type[position].problemType2[position2].id
                                        true
                                    }
                                    .setNegative("取消", null)
                                    .show(parentFragmentManager)
                            }
                            true
                        }
                        .setNegative("取消", null)
                        .show(parentFragmentManager)
                }, {
                    Toaster.show(it.errorMsg)
                })
            }
            file.observe(viewLifecycleOwner) { resultState ->
                parseState(resultState, {
                    log_e("device:" + it.id)
                    imageIds = if (imageIds.isEmpty()) {
                        it.id
                    } else {
                        imageIds + "," + it.id
                    }
                    if (mData.isNotEmpty()) upFile()
                    else {
                        dismissLoading()
                        //Toaster.show("上传成功")
                        add()
                    }
                }, {
                    Toaster.show(it.errorMsg)
                })
            }
            reportAdd.observe(viewLifecycleOwner) { resultState ->
                parseState(resultState, {
                    Toaster.show("提交成功")
                    viewModelScope.launch {
                        delay(500)
                        activity?.finish()
                    }
                }, {
                    Toaster.show(it.errorMsg)
                })
            }
        }

    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(event: EventBusModel) {
        when (event.type) {
            REFRESH_ADDRESS -> {}
            else -> {}
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        EventBus.getDefault().unregister(this)
        destroyLocation()
    }

    override fun onBindViewClick() {
        setOnclickNoRepeat(
            mViewBind.tvName,
            mViewBind.tvAddress,
            mViewBind.tvLaiyuan,
            mViewBind.tvApproveType,
            mViewBind.btCancel,
            mViewBind.btOk,
            mViewBind.tvType
        ) {
            when (it.id) {

                R.id.tv_name -> {
                    // mViewModel.getDeviceType("3")
                }

                R.id.tv_address -> {
                    XXPermissions.with(this)
                        .permission(Permission.ACCESS_COARSE_LOCATION)
                        .permission(Permission.ACCESS_FINE_LOCATION)
                        .permission(Permission.READ_PHONE_STATE)
                        .request(object : OnPermissionCallback {
                            override fun onGranted(permissions: List<String>, all: Boolean) {
                                initLocation()
                            }

                            override fun onDenied(permissions: List<String>, never: Boolean) {}
                        })
                }

                R.id.tv_laiyuan -> {
                    CircleDialog.Builder()
                        .setItems(formTypes) { _, position ->
                            mViewBind.tvLaiyuan.text = formTypes[position].itemLabel
                            form_type = formTypes[position].id
                            true
                        }
                        .setNegative("取消", null)
                        .show(parentFragmentManager)
                }

                R.id.tv_approve_type -> {
                    CircleDialog.Builder()
                        .setItems(approveTypes) { _, position ->
                            mViewBind.tvApproveType.text = approveTypes[position].itemLabel
                            approve_type = approveTypes[position].id
                            true
                        }
                        .setNegative("取消", null)
                        .show(parentFragmentManager)
                }

                R.id.tv_type2,
                R.id.tv_type -> {
                    mViewModel.getProblemType("0")
                }

                R.id.bt_cancel -> {
                    activity?.finish()
                }

                R.id.bt_ok -> {
                    mData.clear()
                    mData.addAll(imageAdapter.data)
                    imageIds = ""
                    address = mViewBind.tvAddress2.text.toString()
                    content = mViewBind.tvContent.text.toString()
                    remark = mViewBind.tvRemark.text.toString()
                    if (latlng == null) {
                        showMessage("请获取当前位置")
                        return@setOnclickNoRepeat
                    }
                    if (content.isEmpty()) {
                        Toaster.show("请输入问题描述")
                        return@setOnclickNoRepeat
                    }
                    if (mData.isNotEmpty()) {
                        showLoading("正在上传图片")
                        upFile()
                    } else {
                        Toaster.show("请上传图片")
                    }
                }
            }
        }
    }

    private fun add() {
        //device_id = "3033"
        mViewModel.reportAdd(
            question_sta, form_type, work_type, son_type, "",
            device_id, latlng.toJsonStr(), address, "1", "", approve_type,
            content, remark, imageIds, ""
        )
    }

    private fun upFile() {
        if (!mData[0].availablePath.isNullOrBlank()) {
            var file = File(mData[0].availablePath)
            mViewModel.upFile(file)
            mData.removeAt(0)
        }else{
            mData.removeAt(0)
            if (mData.isNotEmpty()) upFile()
            else {
                dismissLoading()
                add()
            }
        }

    }

    private fun initLocation() {
        showLoading("定位中")
        locationClient = AMapLocationClient(activity).apply {
            setLocationOption(getDefaultOption())
            setLocationListener(this@ReportAddKtFragment)
            startLocation()
        }
    }

    private fun getDefaultOption(): AMapLocationClientOption {
        val mOption = AMapLocationClientOption().apply {
            locationMode =
                AMapLocationClientOption.AMapLocationMode.Hight_Accuracy //可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
            isOnceLocation = true
            isLocationCacheEnable = true //可选，设置是否使用缓存定位，默认为true
        }
        return mOption
    }


    private fun stopLocation() {
        locationClient.stopLocation()
    }

    private fun destroyLocation() {
        if (::locationClient.isInitialized) {
            locationClient.onDestroy()
        }
    }

    override fun onLocationChanged(location: AMapLocation?) {
        dismissLoading()
        if (null != location) {
            val sb = StringBuffer()
            if (location.errorCode == 0) {
                MmkvUtil.putString("lng", "" + location.longitude)
                MmkvUtil.putString("lat", "" + location.latitude)
                log_e("定位成功 lng=" + location.longitude + "  lat=" + location.latitude)
                log_e("address:" + location.toStr())
                if (!location.address.isNullOrBlank()) {
                    mViewBind.tvAddress2.setText(location.address)
                } else {
                    var point = LatLonPoint(location.latitude, location.longitude)
                    showLoading("定位中...")
                    getAddress(point)
                }
                mViewBind.tvAddress.text =
                    "经度:" + location.longitude + " 纬度:" + location.latitude
                latlng = UpLatLngKt(location.longitude, location.latitude)
//                val g = MapAppUtil.gcj02_To_Gps84(location.latitude, location.longitude)
//                log_e("GPS==" + g[0] + "," + g[1])
            } else {
                log_e("定位失败错误码:${location.errorCode}\n")
                log_e("错误信息:${location.errorInfo}\n")
                log_e("错误描述:${location.locationDetail}\n")
            }
        } else {
            log_e("定位失败，loc is null")
        }
        stopLocation()
    }

    private fun createActivityResultLauncher(): ActivityResultLauncher<Intent> {
        return registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) { result ->
            val resultCode = result.resultCode
            if (resultCode == AppCompatActivity.RESULT_OK) {
                val selectList = PictureSelector.obtainSelectorList(result.data)
                analyticalSelectResults(selectList)
            } else if (resultCode == AppCompatActivity.RESULT_CANCELED) {
                Log.i(TAG, "onActivityResult PictureSelector Cancel")
            }
        }
    }

    private fun analyticalSelectResults(result: java.util.ArrayList<LocalMedia>) {
        for (media in result) {
            if (media.width == 0 || media.height == 0) {
                if (PictureMimeType.isHasImage(media.mimeType)) {
                    val imageExtraInfo =
                        MediaUtils.getImageSize(UMSLEnvelopeBuild.mContext, media.path)
                    media.width = imageExtraInfo.width
                    media.height = imageExtraInfo.height
                } else if (PictureMimeType.isHasVideo(media.mimeType)) {
                    val videoExtraInfo =
                        MediaUtils.getVideoSize(UMSLEnvelopeBuild.mContext, media.path)
                    media.width = videoExtraInfo.width
                    media.height = videoExtraInfo.height
                }
            }
            //val file = File(media.compressPath)
        }
        val isMaxSize = result.size == imageAdapter.selectMax
        val oldSize: Int = imageAdapter.data.size
        imageAdapter.notifyItemRangeRemoved(0, if (isMaxSize) oldSize + 1 else oldSize)
        imageAdapter.data.clear()
        imageAdapter.data.addAll(result)
        imageAdapter.notifyItemRangeInserted(0, result.size)
    }

    override fun onRegeocodeSearched(result: RegeocodeResult?, resultCode: Int) {
        dismissLoading()
        if (resultCode == AMapException.CODE_AMAP_SUCCESS && result != null) {
            mViewBind.tvAddress2.setText(result?.regeocodeAddress?.formatAddress)
        }
    }

    override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
    }

    fun getAddress(latLonPoint: LatLonPoint?) {

        val query = RegeocodeQuery(
            latLonPoint, 200f,
            GeocodeSearch.AMAP
        ) // 第一个参数表示一个Latlng，第二参数表示范围多少米，第三个参数表示是火系坐标系还是GPS原生坐标系
        geocoderSearch.getFromLocationAsyn(query) // 设置异步逆地理编码请求
    }
}